/**
 * Cesium天气效果模块
 * 提供雨和闪电效果的创建与控制
 */
class CesiumWeather {
  /**
   * 构造函数
   * @param {Cesium.Viewer} viewer - Cesium viewer实例
   */
  constructor(viewer) {
    if (!viewer) {
      throw new Error('请传入Cesium Viewer实例');
    }

    this.viewer = viewer;
    this.weatherEffects = null;
    this.lightningStage = null;
    this.lightningEnabled = false;
    this.rainEnabled = false;
  }

  /**
   * 初始化闪电效果的着色器
   */
  initLightningShader() {
    return `
        #version 300 es
        precision highp float;
        
        // 哈希函数 - 支持多种输入类型重载
        float hash(float x) {
            return fract(21654.6512 * sin(385.51 * x));
        }
        
        float hash(vec2 p) {
            return fract(1654.65157 * sin(15.5134763 * p.x + 45.5173247 * p.y + 5.21789));
        }
        
        float hash(vec3 p) {
            return fract(sin(dot(p, vec3(12.9898, 78.233, 45.5432))) * 43758.5453);
        }
        
        // 改进的噪声函数
        float noise(vec2 p) {
            vec2 i = floor(p);
            vec2 f = fract(p);
            
            // 生成网格点的哈希值
            float a = hash(i);
            float b = hash(i + vec2(1.0, 0.0));
            float c = hash(i + vec2(0.0, 1.0));
            float d = hash(i + vec2(1.0, 1.0));
            
            // 平滑插值
            vec2 u = f * f * (3.0 - 2.0 * f);
            return mix(a, b, u.x) + (c - a) * u.y * (1.0 - u.x) + (d - b) * u.x * u.y;
        }
        
        // 改进的FBM函数 - 明确参数类型
        float fbm2(vec2 p) {
            float v = 0.0;
            v += 0.5 * noise(p);
            p *= 2.02;
            v += 0.25 * noise(p);
            p *= 2.03;
            v += 0.125 * noise(p);
            return v;
        }
        
        uniform sampler2D colorTexture;
        uniform float fall_interval;
        uniform float mix_factor;
        in vec2 v_textureCoordinates;
        out vec4 fragColor;
        
        void main(void) {
            // 初始化颜色变量
            vec3 col = vec3(0.0);
            
            // 计算闪电效果
            vec2 uv = v_textureCoordinates;
            float t = fract(fall_interval * 0.1);
            float lightning = 0.0;
            
            // 创建闪电分支效果
            for(int i = 0; i < 3; i++) {
                float layer = float(i);
                float speed = 0.5 + layer * 0.2;
                float scale = 1.0 + layer * 0.5;
                
                vec2 displacement = vec2(fbm2(vec2(uv.y * scale - t * speed, 0.0)), 0.0);
                float branch = fbm2(vec2(uv.y * scale - t * speed + displacement.x * 0.5, 0.0));
                
                // 添加闪电亮度
                lightning += smoothstep(0.4, 0.9, branch) * (0.6 - layer * 0.15);
        }
            
            // 应用闪电颜色
               col += vec3(lightning * 1.8, lightning * 2.2, lightning * 2.8);
            
            // 混合原始图像和闪电效果
            fragColor = mix(texture(colorTexture, v_textureCoordinates), vec4(col, 1.0), mix_factor);
        }
    `;
  }

  /**
   * 创建闪电效果
   * @param {Object} options - 闪电效果参数
   * @param {number} options.mix_factor - 混合系数(0-1)
   * @param {number} options.fall_interval - 下落间隔(0-1)
   */
  createLightning(options = {}) {
        // 清除已有的闪电效果
        if (this.lightningStage) {
            this.viewer.scene.postProcessStages.remove(this.lightningStage);
        }

        // 默认参数
        const defaults = {
            mix_factor: 0.35,
            fall_interval: 0.8
        };

        const config = { ...defaults, ...options };

        // 直接创建后处理阶段，不扩展Cesium库
        this.lightningStage = new Cesium.PostProcessStage({
            name: 'czm_lightning',
            fragmentShader: this.initLightningShader(),
            uniforms: {
                mix_factor: () => config.mix_factor,
                fall_interval: () => config.fall_interval
            }
        });

        this.viewer.scene.postProcessStages.add(this.lightningStage);
        this.lightningEnabled = true;

        return this;
    }

  /**
   * 创建雨效果
   * @param {Object} options - 雨效果参数
   * @param {string} options.name - 效果名称
   */
  createRain(options = {}) {
    // 清除已有的雨效果
    if (this.weatherEffects) {
      this.viewer.scene.primitives.remove(this.weatherEffects);
    }

    const defaults = {
      name: 'rainEffect',
      intensity: 0.5,
      color: new Cesium.Color(0.6, 0.8, 1.0, 0.8)
    };

    const config = { ...defaults, ...options };

    // 使用Cesium粒子系统创建雨效果
    this.weatherEffects = new Cesium.ParticleSystem({
      image: Cesium.buildModuleUrl('Images/white.png'),
      startColor: config.color,
      endColor: config.color.withAlpha(0.0),
      particleLife: 15.0,
      speed: 100.0,
      imageSize: new Cesium.Cartesian2(2, 20),
      emissionRate: 5000 * config.intensity,
      lifetime: 16.0,
      emitter: new Cesium.BoxEmitter(new Cesium.Cartesian3(100000.0, 100000.0, 5000.0)),
      updateCallback: (particle, dt) => {
        particle.position.add(new Cesium.Cartesian3(
          Cesium.Math.nextRandomNumber() * 10 - 5,
          Cesium.Math.nextRandomNumber() * 10 - 5,
          -100.0 * dt
        ));
      }
    });

    this.viewer.scene.primitives.add(this.weatherEffects);
    this.rainEnabled = true;

    return this;
  }

  /**
   * 开启或关闭闪电效果
   * @param {boolean} enabled - 是否开启
   */
  toggleLightning(enabled) {
    if (this.lightningStage) {
      this.lightningStage.enabled = enabled;
      this.lightningEnabled = enabled;
    }
    return this;
  }

  /**
   * 开启或关闭雨效果
   * @param {boolean} enabled - 是否开启
   */
  toggleRain(enabled) {
    if (this.weatherEffects && typeof this.weatherEffects.setEnabled === 'function') {
      this.weatherEffects.setEnabled(enabled);
      this.rainEnabled = enabled;
    }
    return this;
  }

  /**
   * 更新闪电效果参数
   * @param {Object} options - 要更新的参数
   */
  updateLightningOptions(options) {
    if (this.lightningStage) {
      Object.keys(options).forEach(key => {
        if (this.lightningStage.uniforms.hasOwnProperty(key)) {
          this.lightningStage.uniforms[key] = options[key];
        }
      });
    }
    return this;
  }

  /**
   * 销毁所有天气效果
   */
  destroy() {
    // 销毁闪电效果
    if (this.lightningStage) {
      this.viewer.scene.postProcessStages.remove(this.lightningStage);
      this.lightningStage = null;
    }

    // 销毁雨效果
    if (this.weatherEffects && typeof this.weatherEffects.destroy === 'function') {
      this.weatherEffects.destroy();
      this.weatherEffects = null;
    }

    this.lightningEnabled = false;
    this.rainEnabled = false;
  }
}
export default CesiumWeather
